#include "SDL2/SDL.h"
#include <iostream>
#include "SDL2/SDL_ttf.h"
#include "SDL2/SDL_image.h"
#include <stdexcept>
#include <string>
#include "Actor.h"

//定义屏幕尺寸常量
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;

using namespace std;

SDL_Texture* LoadImage(SDL_Renderer *renderer, string file)
{
    SDL_Texture* tex = nullptr;
    tex = IMG_LoadTexture(renderer, file.c_str());
    if (tex == nullptr)
    {
        throw runtime_error("Failed to load image: " + file + IMG_GetError());
    }
    return tex;
}


void ApplySurface(int x, int y, SDL_Texture *tex, SDL_Renderer *rend, SDL_Rect *clip = NULL)
{
    SDL_Rect pos;
    pos.x = x;
    pos.y = y;
    //Detect if we should use clip width settings or texture width
    if (clip != NULL)
    {
        pos.w = clip->w;
	    pos.h = clip->h;
    }
    else
    {
        SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
    }
    SDL_RenderCopy(rend, tex, clip, &pos);
}


SDL_Texture* RenderText(SDL_Renderer *renderer, string message, string fontFile, SDL_Color color, int fontSize)
{
    //Open the font
    TTF_Font *font = nullptr;
    font = TTF_OpenFont(fontFile.c_str(), fontSize);
    if (font == nullptr)
        throw std::runtime_error("Failed to load font: " + fontFile + TTF_GetError());
	
    //Render the message to an SDL_Surface, as that's what TTF_RenderText_X returns
    SDL_Surface *surf = TTF_RenderText_Blended(font, message.c_str(), color);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
    //Clean up unneeded stuff
    SDL_FreeSurface(surf);
    TTF_CloseFont(font);

    return texture;
}

int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;

    SDL_Texture *background = nullptr;
    SDL_Window *window = nullptr;
    SDL_Renderer *renderer = nullptr;
    SDL_Event event;
    int quit = false;
    Actor myActor;

    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        cout << SDL_GetError() << endl;
        return 1;
    }

    if (TTF_Init() == -1)
    {
        cout << TTF_GetError() << endl;
        return 1;
    }
 
    window = SDL_CreateWindow("PNG TRAN", SDL_WINDOWPOS_CENTERED, 
        SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
    if (window == nullptr)
    {
        cout << SDL_GetError() << endl;
        return 2;
    }

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == nullptr)
    {
        cout << SDL_GetError() << endl;
        return 3;
    }

    try
    {
        background = LoadImage(renderer, "../assert/background.png");
    }
    catch (const runtime_error &e)
    {
        cout << e.what() << endl;
	    return 4;
    }

    myActor.setBackground(renderer, "../assert/actor.png");


    SDL_Texture *image = nullptr;
    try 
    {
        SDL_Color color = { 255, 255, 0, 128};
        image = RenderText(renderer, "TTF fonts are cool!", "../assert/lazy.ttf", color, 32);
    }
    catch (const std::runtime_error &e)
    {
        std::cout << e.what() << std::endl;
        return 4;
    }

    //当用户还不想退出时
    while( quit == false )
    {
        SDL_RenderClear(renderer);

        ApplySurface(0, 0, background, renderer, NULL);
        ApplySurface(100, 100, image, renderer, NULL);
        
        myActor.show(renderer);
        SDL_RenderPresent(renderer);

        //当有事件发生时，我们需要处理它们
        while( SDL_PollEvent( &event ) )
        {
            //如果用户点击了窗口右上角的关闭按钮
            switch( event.type )
            {
                case SDL_QUIT:
                    //退出程序
                    quit = true;
                break;
            }

            myActor.handleEvent(event);
        }

		SDL_Delay(20);
    }

    SDL_DestroyTexture(background);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
 
    SDL_Quit();
  
    return 0;
}